package lu.med.praxiswahl.wahlumed.client.forms;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import lu.med.praxiswahl.wahlumed.client.formdesigner.FormDesignerModelListener;

/**
 * 
 * @author Lars Holger Roth
 */
public class FormsFileFormat {

	private ArrayList<FormDesignerModelListener> listener = new ArrayList<FormDesignerModelListener>();
	// Die Daten des Formulars
	private ArrayList<ArrayList<String>> entry;
	private ArrayList<ArrayList<Integer>> entryX;
	private ArrayList<ArrayList<Integer>> entryY;
	private int pages = 1; // Anzahl der Seiten
	// Das zugehörige Bitmap
	private String[] imagePath;
	private static final String fileFormatInformation = "FORM V000";

	public FormsFileFormat(String fileName, int pages) {
		// Standard Aktionen
		this.pages = pages;

		// Bilder Pfade
		imagePath = new String[pages];
		for (int i = 0; i < pages; i++)
			imagePath[i] = "";

		// Erstellt die Array Listen
		entry = new ArrayList<ArrayList<String>>();
		entryX = new ArrayList<ArrayList<Integer>>();
		entryY = new ArrayList<ArrayList<Integer>>();

		// Erstellt die Listen für die einzelnen Seiten
		for (int i = 0; i < pages; i++) {
			entry.add(new ArrayList<String>());
			entryX.add(new ArrayList<Integer>());
			entryY.add(new ArrayList<Integer>());
		}

		if (!fileName.equals("")) {
			loadFromFile(fileName);
		}
	}

	public void addListener(FormDesignerModelListener l) {
		listener.add(l);
	}

	public void clear() {
		for (int i = 0; i < entry.size(); i++) {
			entry.get(i).clear();
			entryX.get(i).clear();
			entryY.get(i).clear();
		}
	}

	public void createObjectPosition(String text, int x, int y, int page) {
		entry.get(page).add(text);
		entryX.get(page).add(x);
		entryY.get(page).add(y);
		this.fireModelChanged();
	}

	public void deleteObject(int index, int page) {
		if (index < entry.get(page).size()) {
			entry.get(page).remove(index);
			entryX.get(page).remove(index);
			entryY.get(page).remove(index);
			this.fireModelChanged();
		}
	}

	public void fireModelChanged() {
		for (int i = 0; i < listener.size(); i++) {
			listener.get(i).modelChanged();
		}
	}

	public ArrayList<String> getEntry(int page) {
		return entry.get(page);
	}

	public ArrayList<Integer> getEntryX(int page) {
		return entryX.get(page);
	}

	public ArrayList<Integer> getEntryY(int page) {
		return entryY.get(page);
	}

	public String[] getImagePath() {
		return imagePath;
	}

	public int getPages() {
		return pages;
	}

	public void loadFromFile(String fileName) {
		try {
			File file = new File(fileName);
			FileInputStream iStream = new FileInputStream(file);
			ObjectInputStream fileStream = new ObjectInputStream(iStream);

			fileStream.readUTF(); // Version, wird später möglicherweise
			// benutzt

			// Liest die Anzahl der Seiten aus
			pages = fileStream.readInt();

			// Erstellt die Array Listen
			entry = new ArrayList<ArrayList<String>>();
			entryX = new ArrayList<ArrayList<Integer>>();
			entryY = new ArrayList<ArrayList<Integer>>();

			// Erstellt die Listen für die einzelnen Seiten
			for (int i = 0; i < pages; i++) {
				entry.add(new ArrayList<String>());
				entryX.add(new ArrayList<Integer>());
				entryY.add(new ArrayList<Integer>());
			}

			for (int i = 0; i < pages; i++) {
				int size = fileStream.readInt();
				for (int ii = 0; ii < size; ii++) {
					entry.get(i).add(fileStream.readUTF());
					entryX.get(i).add(fileStream.readInt());
					entryY.get(i).add(fileStream.readInt());
				}
			}

			// Anzahl der Grafiken laden
			imagePath = new String[pages];
			for (int i = 0; i < pages; i++)
				imagePath[i] = fileStream.readUTF();

			fileStream.close();
		} catch (IOException io) {
			JOptionPane.showMessageDialog(null,
					"Es trat ein Fehler beim Lesen der Datei " + fileName
							+ " auf.");
		}
	}

	public void removeListener(FormDesignerModelListener l) {
		listener.remove(l);
	}

	public void reset() {
		// Behält Formulartypische Daten bei und setzt alle Einträge
		// zurück. Bezieht sich auf alle Seiten
		entry.clear();
		entryX.clear();
		entryY.clear();
	}

	public void saveToFile(String fileName) {
		try {
			File file = new File(fileName);
			FileOutputStream oStream = new FileOutputStream(file);
			ObjectOutputStream fileStream = new ObjectOutputStream(oStream);

			// Schreibt die Versionsinformation
			fileStream.writeUTF(fileFormatInformation);

			// Schreibt die Anzahl der Seiten
			fileStream.writeInt(pages);

			for (int i = 0; i < pages; i++) {
				// Schreibt die Anzahl der Datensätze
				fileStream.writeInt(entry.get(i).size());
				// Schreibt die Datensätze
				for (int ii = 0; ii < entry.get(i).size(); ii++) {
					fileStream.writeUTF(entry.get(i).get(ii));
					fileStream.writeInt(entryX.get(i).get(ii));
					fileStream.writeInt(entryY.get(i).get(ii));
				}
			}

			// Schreibt den Image Path
			for (int i = 0; i < pages; i++)
				fileStream.writeUTF(imagePath[i]);

			fileStream.close();
		} catch (IOException io) {
			JOptionPane.showMessageDialog(null,
					"Es trat ein Fehler beim Schreiben der Datei " + fileName
							+ " auf.");
		}
	}

	public void setEntry(ArrayList<String> entry, int page) {
		this.entry.set(page, entry);
	}

	public void setEntryX(ArrayList<Integer> entryX, int page) {
		this.entryX.set(page, entryX);
	}

	public void setEntryY(ArrayList<Integer> entryY, int page) {
		this.entryY.set(page, entryY);
	}

	public void setImagePath(String[] imagePath) {
		this.imagePath = imagePath;
	}

	public int size(int page) {
		return entry.get(page).size();
	}
}
